Span<T> 구조체
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
임의 메모리의 연속 영역의 형식 안전 및 메모리로부터 안전한 표현을 제공합니다.
generic <typename T>
public value class Span
[System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))]
public readonly ref struct Span<T>
public readonly ref struct Span<T>
[<System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))>]
type Span<'T> = struct
type Span<'T> = struct
Public Structure Span(Of T)
형식 매개 변수
- T
에 있는 항목의 형식입니다 Span<T>.
- 상속
- 특성
설명
형식은 관리되는 힙이 아닌 스택에 할당된 Span<T>ref 구조체입니다. Ref 구조체 형식에는 다음과 같이 관리되는 힙으로 승격할 수 없도록 몇 가지 제한 사항이 있습니다.
- 박스형.
- 형식 또는 형식 Object 의 변수 또는
dynamic인터페이스 형식에 할당됩니다. - 참조 형식의 필드입니다.
- 경계를 넘어
awaityield사용됩니다.
또한, 두 메서드 Equals(Object)와 GetHashCode를 호출하면 NotSupportedException가 발생합니다.
Important
스택 전용 형식 Span<T> 이므로 힙의 버퍼에 대한 참조를 저장해야 하는 많은 시나리오에서는 적합하지 않습니다. 예를 들어 비동기 메서드를 호출하는 루틴의 경우도 마찬가지입니다. 이러한 시나리오의 경우 보완 System.Memory<T> 및 System.ReadOnlyMemory<T> 형식을 사용할 수 있습니다.
변경할 수 없거나 읽기 전용 구조를 나타내는 범위에는 System.ReadOnlySpan<T>를 사용하십시오.
기억
A Span<T> 는 임의 메모리의 연속 영역을 나타냅니다.
Span<T> 인스턴스는 배열의 요소 또는 배열의 일부를 보유하는 데 자주 사용됩니다. 그러나 배열과 달리 인스턴스는 Span<T> 스택에서 관리되는 메모리, 네이티브 메모리 또는 메모리를 가리킬 수 있습니다. 다음 예제에서는 배열에서 Span<Byte>를 생성합니다.
// Create a span over an array.
var array = new byte[100];
var arraySpan = new Span<byte>(array);
byte data = 0;
for (int ctr = 0; ctr < arraySpan.Length; ctr++)
arraySpan[ctr] = data++;
int arraySum = 0;
foreach (var value in array)
arraySum += value;
Console.WriteLine($"The sum is {arraySum}");
// Output: The sum is 4950
// Create a span over an array.
let array = Array.zeroCreate<byte> 100
let arraySpan = Span<byte> array
let mutable data = 0uy
for i = 0 to arraySpan.Length - 1 do
arraySpan[i] <- data
data <- data + 1uy
let mutable arraySum = 0
for value in array do
arraySum <- arraySum + int value
printfn $"The sum is {arraySum}"
// Output: The sum is 4950
다음 예제에서는 100바이트의 네이티브 메모리에서 Span<Byte>를 생성합니다.
// Create a span from native memory.
var native = Marshal.AllocHGlobal(100);
Span<byte> nativeSpan;
unsafe
{
nativeSpan = new Span<byte>(native.ToPointer(), 100);
}
byte data = 0;
for (int ctr = 0; ctr < nativeSpan.Length; ctr++)
nativeSpan[ctr] = data++;
int nativeSum = 0;
foreach (var value in nativeSpan)
nativeSum += value;
Console.WriteLine($"The sum is {nativeSum}");
Marshal.FreeHGlobal(native);
// Output: The sum is 4950
// Create a span from native memory.
let native = Marshal.AllocHGlobal 100
let nativeSpan = Span<byte>(native.ToPointer(), 100)
let mutable data = 0uy
for i = 0 to nativeSpan.Length - 1 do
nativeSpan[i] <- data
data <- data + 1uy
let mutable nativeSum = 0
for value in nativeSpan do
nativeSum <- nativeSum + int value
printfn $"The sum is {nativeSum}"
Marshal.FreeHGlobal native
// Output: The sum is 4950
다음 예제에서는 C# stackalloc 키워드를 사용하여 스택에 100바이트의 메모리를 할당합니다.
// Create a span on the stack.
byte data = 0;
Span<byte> stackSpan = stackalloc byte[100];
for (int ctr = 0; ctr < stackSpan.Length; ctr++)
stackSpan[ctr] = data++;
int stackSum = 0;
foreach (var value in stackSpan)
stackSum += value;
Console.WriteLine($"The sum is {stackSum}");
// Output: The sum is 4950
// Create a span on the stack.
let mutable data = 0uy
let stackSpan =
let p = NativeInterop.NativePtr.stackalloc<byte> 100 |> NativeInterop.NativePtr.toVoidPtr
Span<byte>(p, 100)
for i = 0 to stackSpan.Length - 1 do
stackSpan[i] <- data
data <- data + 1uy
let mutable stackSum = 0
for value in stackSpan do
stackSum <- stackSum + int value
printfn $"The sum is {stackSum}"
// Output: The sum is 4950
Span<T> 임의의 메모리 블록에 대한 추상화이므로 형식의 Span<T> 메서드와 매개 변수가 포함된 Span<T> 메서드는 캡슐화된 메모리 종류에 관계없이 모든 Span<T> 개체에서 작동합니다. 예를 들어, 다음 예제와 같이 범위를 초기화하고 해당 요소의 합계를 계산하는 코드의 각 개별 섹션을 단일 초기화 및 계산 메서드로 리팩터링할 수 있습니다.
public static void WorkWithSpans()
{
// Create a span over an array.
var array = new byte[100];
var arraySpan = new Span<byte>(array);
InitializeSpan(arraySpan);
Console.WriteLine($"The sum is {ComputeSum(arraySpan):N0}");
// Create an array from native memory.
var native = Marshal.AllocHGlobal(100);
Span<byte> nativeSpan;
unsafe
{
nativeSpan = new Span<byte>(native.ToPointer(), 100);
}
InitializeSpan(nativeSpan);
Console.WriteLine($"The sum is {ComputeSum(nativeSpan):N0}");
Marshal.FreeHGlobal(native);
// Create a span on the stack.
Span<byte> stackSpan = stackalloc byte[100];
InitializeSpan(stackSpan);
Console.WriteLine($"The sum is {ComputeSum(stackSpan):N0}");
}
public static void InitializeSpan(Span<byte> span)
{
byte value = 0;
for (int ctr = 0; ctr < span.Length; ctr++)
span[ctr] = value++;
}
public static int ComputeSum(Span<byte> span)
{
int sum = 0;
foreach (var value in span)
sum += value;
return sum;
}
// The example displays the following output:
// The sum is 4,950
// The sum is 4,950
// The sum is 4,950
open System
open System.Runtime.InteropServices
open FSharp.NativeInterop
// Package FSharp.NativeInterop.NativePtr.stackalloc for reuse.
let inline stackalloc<'a when 'a: unmanaged> length : Span<'a> =
let voidPointer = NativePtr.stackalloc<'a> length |> NativePtr.toVoidPtr
Span<'a>(voidPointer, length)
let initializeSpan (span: Span<byte>) =
let mutable value = 0uy
for i = 0 to span.Length - 1 do
span[i] <- value
value <- value + 1uy
let computeSum (span: Span<byte>) =
let mutable sum = 0
for value in span do
sum <- sum + int value
sum
let workWithSpans () =
// Create a span over an array.
let array = Array.zeroCreate<byte> 100
let arraySpan = Span<byte> array
initializeSpan arraySpan
printfn $"The sum is {computeSum arraySpan:N0}"
// Create an array from native memory.
let native = Marshal.AllocHGlobal 100
let nativeSpan = Span<byte>(native.ToPointer(), 100)
initializeSpan nativeSpan
printfn $"The sum is {computeSum nativeSpan:N0}"
Marshal.FreeHGlobal native
// Create a span on the stack.
let stackSpan = stackalloc 100
initializeSpan stackSpan
printfn $"The sum is {computeSum stackSpan:N0}"
// The example displays the following output:
// The sum is 4,950
// The sum is 4,950
// The sum is 4,950
배열
배열 Span<T> 을 래핑할 때 메모리 섹션의 예제에서와 같이 전체 배열을 래핑할 수 있습니다. 슬라이싱을 지원하므로, Span<T>는 배열 내의 인접한 범위를 가리킬 수도 있습니다.
다음 예제에서는 10개 요소 정수 배열의 중간 5개 요소 조각을 만듭니다. 코드는 조각에 있는 각 정수의 값을 두 배로 둡니다. 출력에서 보여 주듯이 범위에 의해 변경된 내용은 배열 값에 반영됩니다.
using System;
var array = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
var slice = new Span<int>(array, 2, 5);
for (int ctr = 0; ctr < slice.Length; ctr++)
slice[ctr] *= 2;
// Examine the original array values.
foreach (var value in array)
Console.Write($"{value} ");
Console.WriteLine();
// The example displays the following output:
// 2 4 12 16 20 24 28 16 18 20
module Program
open System
[<EntryPoint>]
let main _ =
let array = [| 2; 4; 6; 8; 10; 12; 14; 16; 18; 20 |]
let slice = Span<int>(array, 2, 5)
for i = 0 to slice.Length - 1 do
slice[i] <- slice[i] * 2
// Examine the original array values.
for value in array do
printf $"{value} "
printfn ""
0
// The example displays the following output:
// 2 4 12 16 20 24 28 16 18 20
조각
Span<T>에는 지정된 인덱스에서 시작하여 현재 범위에서 조각을 형성하는 Slice 메서드의 두 가지 오버로드가 포함됩니다. 이렇게 하면 데이터를 최소한의 성능 영향으로 데이터 처리 파이프라인의 일부에서 Span<T> 필요에 따라 처리할 수 있는 논리 청크 집합으로 처리할 수 있습니다. 예를 들어 최신 서버 프로토콜은 종종 텍스트 기반이므로 문자열 및 부분 문자열을 조작하는 것이 특히 중요합니다.
String 클래스에서 부분 문자열을 추출하는 주요 메서드는 .입니다Substring. 광범위한 문자열 조작을 사용하는 데이터 파이프라인의 경우 다음과 같은 이유로 성능이 저하됩니다.
- 부분 문자열을 저장할 새 문자열을 만듭니다.
- 원래 문자열에서 새 문자열로 문자의 하위 집합을 복사합니다.
이 할당 및 복사 작업은 다음 예제와 같이 사용 Span<T> 하거나 ReadOnlySpan<T>사용하여 제거할 수 있습니다.
using System;
class Program2
{
static void Run()
{
string contentLength = "Content-Length: 132";
var length = GetContentLength(contentLength.ToCharArray());
Console.WriteLine($"Content length: {length}");
}
private static int GetContentLength(ReadOnlySpan<char> span)
{
var slice = span.Slice(16);
return int.Parse(slice);
}
}
// Output:
// Content length: 132
module Program2
open System
let getContentLength (span: ReadOnlySpan<char>) =
let slice = span.Slice 16
Int32.Parse slice
let contentLength = "Content-Length: 132"
let length = getContentLength (contentLength.ToCharArray())
printfn $"Content length: {length}"
// Output:
// Content length: 132
생성자
| Name | Description |
|---|---|
| Span<T>(T) |
지정된 참조 주위에 길이 1을 새로 Span<T> 만듭니다. |
| Span<T>(T[], Int32, Int32) |
지정된 인덱스에서 시작하는 배열의 지정된 개수의 요소를 포함하는 새 Span<T> 개체를 만듭니다. |
| Span<T>(T[]) |
Span<T> 지정된 배열 전체에 새 개체를 만듭니다. |
| Span<T>(Void*, Int32) |
지정된 메모리 주소에서 시작하는 지정된 수의 Span<T> 요소에서 새 |
속성
| Name | Description |
|---|---|
| Empty |
빈 Span<T> 개체를 반환합니다. |
| IsEmpty |
현재 Span<T> 가 비어 있는지 여부를 나타내는 값을 반환합니다. |
| Item[Int32] |
지정된 0부터 시작하는 인덱스에서 요소를 가져옵니다. |
| Length |
현재 범위의 길이를 반환합니다. |
메서드
| Name | Description |
|---|---|
| Clear() |
이 Span<T> 개체의 내용을 지웁니다. |
| CopyTo(Span<T>) | |
| Equals(Object) |
사용되지 않음.
사용되지 않음.
이 메서드에 대한 호출은 지원되지 않습니다. |
| Fill(T) |
이 범위의 요소를 지정된 값으로 채웁니다. |
| GetEnumerator() |
이 Span<T>열거자를 반환합니다. |
| GetHashCode() |
사용되지 않음.
NotSupportedException를 throw합니다. |
| GetPinnableReference() |
고정에 사용할 수 있는 T 형식의 개체에 대한 참조를 반환합니다. 이 메서드는 .NET 컴파일러를 지원하기 위한 것이며 사용자 코드에서 호출할 수 없습니다. |
| Slice(Int32, Int32) |
지정된 길이에 대해 지정된 인덱스에서 시작하여 현재 범위에서 조각을 만듭니다. |
| Slice(Int32) |
지정된 인덱스에서 시작하는 현재 범위에서 조각을 형성합니다. |
| ToArray() |
이 범위의 내용을 새 배열에 복사합니다. |
| ToString() |
이 Span<T> 개체의 문자열 표현을 반환합니다. |
| TryCopyTo(Span<T>) |
현재 Span<T> 를 대상으로 Span<T> 복사하려고 시도하고 복사 작업이 성공했는지 여부를 나타내는 값을 반환합니다. |
연산자
| Name | Description |
|---|---|
| Equality(Span<T>, Span<T>) |
두 Span<T> 개체가 같은지 여부를 나타내는 값을 반환합니다. |
| Implicit(ArraySegment<T> to Span<T>) |
에 대한 암시적 변환을 ArraySegment<T> 정의합니다 Span<T>. |
| Implicit(Span<T> to ReadOnlySpan<T>) |
에 대한 암시적 변환을 Span<T> 정의합니다 ReadOnlySpan<T>. |
| Implicit(T[] to Span<T>) |
배열을 .로의 암시적 변환을 정의합니다 Span<T>. |
| Inequality(Span<T>, Span<T>) |
두 Span<T> 개체가 같지 않은지 여부를 나타내는 값을 반환합니다. |
확장명 메서드
| Name | Description |
|---|---|
| BinarySearch<T,TComparable>(Span<T>, TComparable) |
지정된 Span<T> 제네릭 형식을 사용하여 정렬된 |
| BinarySearch<T,TComparer>(Span<T>, T, TComparer) |
지정된 제네릭 형식을 사용하여 Span<T> 정렬된 |
| BinarySearch<T>(Span<T>, IComparable<T>) |
지정된 Span<T> 제네릭 인터페이스를 사용하여 정렬된 IComparable<T> 전체 값을 검색합니다. |
| CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
공유 |
| CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>) |
공유 |
| Contains<T>(Span<T>, T) |
지정한 값이 범위에 있는지 여부를 나타냅니다. |
| ContainsAny<T>(Span<T>, ReadOnlySpan<T>) |
지정된 |
| ContainsAny<T>(Span<T>, SearchValues<T>) |
지정된 |
| ContainsAny<T>(Span<T>, T, T, T) |
또는 지정된 범위에서 발생 |
| ContainsAny<T>(Span<T>, T, T) |
찾은 항목 또는 |
| ContainsAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
지정된 범위에서 지정된 값 이외의 값을 검색합니다 |
| ContainsAnyExcept<T>(Span<T>, SearchValues<T>) |
지정된 범위에서 지정된 값 이외의 값을 검색합니다 |
| ContainsAnyExcept<T>(Span<T>, T, T, T) |
, |
| ContainsAnyExcept<T>(Span<T>, T, T) |
지정된 범위에서 값이 아닌 |
| ContainsAnyExcept<T>(Span<T>, T) |
지정된 범위에서 지정된 값 이외의 값을 검색합니다 |
| ContainsAnyExceptInRange<T>(Span<T>, T, T) |
범위 외부 |
| ContainsAnyInRange<T>(Span<T>, T, T) |
범위의 |
| Count<T>(Span<T>, ReadOnlySpan<T>) |
에서 지정된 |
| Count<T>(Span<T>, T) |
에서 지정된 |
| EndsWith<T>(Span<T>, ReadOnlySpan<T>) |
지정된 시퀀스가 범위의 끝에 표시되는지 여부를 결정합니다. |
| IndexOf<T>(Span<T>, ReadOnlySpan<T>) |
지정된 시퀀스를 검색하고 첫 번째 항목의 인덱스를 반환합니다. |
| IndexOf<T>(Span<T>, T) |
지정된 값을 검색하고 첫 번째 항목의 인덱스가 반환됩니다. |
| IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
지정된 값의 첫 번째 인덱스 검색 |
| IndexOfAny<T>(Span<T>, SearchValues<T>) |
지정된 값의 첫 번째 인덱스 검색 |
| IndexOfAny<T>(Span<T>, T, T, T) |
지정된 값의 첫 번째 인덱스 검색 |
| IndexOfAny<T>(Span<T>, T, T) |
지정된 값의 첫 번째 인덱스 검색 |
| IndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
지정된 |
| IndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
지정된 |
| IndexOfAnyExcept<T>(Span<T>, T, T, T) |
또는 . 이외의 값 |
| IndexOfAnyExcept<T>(Span<T>, T, T) |
지정된 두 값 이외의 값의 첫 번째 인덱스 검색 |
| IndexOfAnyExcept<T>(Span<T>, T) |
지정된 |
| IndexOfAnyExceptInRange<T>(Span<T>, T, T) |
범위에서 벗어나는 값의 첫 번째 인덱스( |
| IndexOfAnyInRange<T>(Span<T>, T, T) |
범위에서 값의 첫 번째 인덱스( |
| LastIndexOf<T>(Span<T>, ReadOnlySpan<T>) |
지정된 시퀀스를 검색하고 마지막으로 발생한 인덱스를 반환합니다. |
| LastIndexOf<T>(Span<T>, T) |
지정된 값을 검색하고 마지막으로 발생한 인덱스가 반환됩니다. |
| LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
지정된 값의 마지막 인덱스 검색 |
| LastIndexOfAny<T>(Span<T>, SearchValues<T>) |
지정된 값의 마지막 인덱스 검색 |
| LastIndexOfAny<T>(Span<T>, T, T, T) |
지정된 값의 마지막 인덱스 검색 |
| LastIndexOfAny<T>(Span<T>, T, T) |
지정된 값의 마지막 인덱스 검색 |
| LastIndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
지정된 |
| LastIndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
지정된 |
| LastIndexOfAnyExcept<T>(Span<T>, T, T, T) |
지정된 |
| LastIndexOfAnyExcept<T>(Span<T>, T, T) |
지정된 |
| LastIndexOfAnyExcept<T>(Span<T>, T) |
지정된 |
| LastIndexOfAnyExceptInRange<T>(Span<T>, T, T) |
범위에서 벗어나는 값의 마지막 인덱스( |
| LastIndexOfAnyInRange<T>(Span<T>, T, T) |
범위에서 값의 마지막 인덱스( |
| Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32) |
범위와 읽기 전용 범위가 메모리에서 겹치는지 여부를 확인하고 요소 오프셋을 출력합니다. |
| Overlaps<T>(Span<T>, ReadOnlySpan<T>) |
메모리에서 범위 및 읽기 전용 범위가 겹치는지 여부를 결정합니다. |
| Replace<T>(Span<T>, T, T, IEqualityComparer<T>) |
|
| Replace<T>(Span<T>, T, T) |
|
| ReplaceAny<T>(Span<T>, SearchValues<T>, T) |
에 있는 |
| ReplaceAnyExcept<T>(Span<T>, SearchValues<T>, T) |
에 있는 |
| Reverse<T>(Span<T>) |
전체 범위에서 요소의 시퀀스를 반대로 바꿉니다. |
| SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>) |
IComparable{T}을 사용하여 요소를 비교하여 범위 및 읽기 전용 범위의 상대 순서를 결정합니다. CompareTo(T). |
| SequenceEqual<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
를 사용하여 IEqualityComparer<T>요소를 비교하여 두 시퀀스가 같은지 여부를 확인합니다. |
| SequenceEqual<T>(Span<T>, ReadOnlySpan<T>) |
IEquatable{T}을 사용하여 요소를 비교하여 범위와 읽기 전용 범위가 같은지 여부를 결정합니다. Equals(T). |
| Sort<T,TComparer>(Span<T>, TComparer) |
를 사용하여 전체 Span<T> 요소를 정렬합니다 |
| Sort<T>(Span<T>, Comparison<T>) |
지정된 요소를 사용하여 전체 Span<T> 요소를 정렬합니다 Comparison<T>. |
| Sort<T>(Span<T>) |
각 요소의 구현을 사용하여 전체 Span<T> 요소를 정렬합니다IComparable<T>.Span<T> |
| Sort<TKey,TValue,TComparer>(Span<TKey>, Span<TValue>, TComparer) |
지정한 비교자를 사용하여 첫 번째 Span<T> 키에 따라 범위 쌍(키를 포함하는 범위와 해당 항목이 들어 있는 범위)을 정렬합니다. |
| Sort<TKey,TValue>(Span<TKey>, Span<TValue>, Comparison<TKey>) |
지정한 비교를 사용하여 첫 번째 Span<T> 키에 따라 범위 쌍(키가 포함된 범위와 해당 항목이 포함된 범위)을 정렬합니다. |
| Sort<TKey,TValue>(Span<TKey>, Span<TValue>) |
각 키의 구현을 사용하여 Span<T> 첫 번째 IComparable<T> 키에 따라 범위 쌍(키를 포함하는 범위와 해당 항목을 포함하는 범위)을 정렬합니다. |
| StartsWith<T>(Span<T>, ReadOnlySpan<T>) |
지정된 시퀀스가 범위의 시작 부분에 표시되는지 여부를 결정합니다. |
| ToImmutableArray<T>(Span<T>) |
범위를 변경할 수 없는 배열로 변환합니다. |
| Trim<T>(Span<T>, ReadOnlySpan<T>) |
범위에서 읽기 전용 범위에 지정된 요소 집합의 선행 및 후행 항목을 모두 제거합니다. |
| Trim<T>(Span<T>, T) |
범위에서 지정된 요소의 선행 및 후행 항목을 모두 제거합니다. |
| TrimEnd<T>(Span<T>, ReadOnlySpan<T>) |
범위에서 읽기 전용 범위에 지정된 요소 집합의 후행 항목을 모두 제거합니다. |
| TrimEnd<T>(Span<T>, T) |
범위에서 지정된 요소의 후행 항목을 모두 제거합니다. |
| TrimStart<T>(Span<T>, ReadOnlySpan<T>) |
범위에서 읽기 전용 범위에 지정된 요소 집합의 선행 항목을 모두 제거합니다. |
| TrimStart<T>(Span<T>, T) |
범위에서 지정된 요소의 선행 항목을 모두 제거합니다. |